using AutoMapper;
using B.S.Medical.Api.Write.Application.Command.Doctor;
using B.S.Medical.Domain.Doctor;
using B.S.Medical.ErrorCode;
using B.S.Medical.Infrastructure;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;

namespace B.S.Medical.Api.Write.Application.Handler.Doctor
{
    /// <summary>
    /// 医生新增处理器
    /// </summary>
    public class CreateDoctorHandler : IRequestHandler<CreateDoctorCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<DoctorModel> _doctorRepository;
        private readonly IBaseRepository<DoctorLabelModel> _doctorLabelRepository;
        private readonly IMapper _mapper;
        private readonly ILogger<CreateDoctorHandler> _logger;
        private readonly MyDbContext _dbContext;

        /// <summary>
        /// 构造函数
        /// </summary>
        public CreateDoctorHandler(IBaseRepository<DoctorModel> doctorRepository, 
                                  IBaseRepository<DoctorLabelModel> doctorLabelRepository, 
                                  IMapper mapper, 
                                  ILogger<CreateDoctorHandler> logger, 
                                  MyDbContext dbContext)
        {
            _doctorRepository = doctorRepository;
            _doctorLabelRepository = doctorLabelRepository;
            _mapper = mapper;
            _logger = logger;
            _dbContext = dbContext;
        }

        /// <summary>
        /// 处理医生新增命令
        /// </summary>
        /// <param name="request">医生新增命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>返回结果</returns>
        public async Task<ApiResult<int>> Handle(CreateDoctorCommand request, CancellationToken cancellationToken)
        {
            ApiResult<int> res = new ApiResult<int>();
            try
            {
                // 开始事务
                using (var transaction = await _dbContext.Database.BeginTransactionAsync(cancellationToken))
                {
                    try
                    {
                        var doctor = _mapper.Map<DoctorModel>(request);
                        doctor.IsDeleted = false;

                        var r = await _doctorRepository.CreateAsync(doctor);
                        if (r > 0)
                        {
                            // 处理标签
                            if (request.LaberIds != null && request.LaberIds.Count > 0)
                            {
                                List<DoctorLabelModel> doctorLabels = new List<DoctorLabelModel>();
                                foreach (var laberId in request.LaberIds)
                                {
                                    doctorLabels.Add(new DoctorLabelModel
                                    {
                                        DoctorId = doctor.Id,
                                        LaberId = laberId,
                                        IsDeleted = false
                                    });
                                }

                                // 批量添加标签关系
                                foreach (var label in doctorLabels)
                                {
                                    await _dbContext.Set<DoctorLabelModel>().AddAsync(label, cancellationToken);
                                }
                                await _dbContext.SaveChangesAsync(cancellationToken);
                            }

                            // 提交事务
                            await transaction.CommitAsync(cancellationToken);

                            res.Msg = "新增医生成功!";
                            res.Code = ApiEnum.Success;
                            _logger.LogInformation($"新增医生成功，ID:{doctor.Id}");
                            res.Data = doctor.Id;
                        }
                        else
                        {
                            // 回滚事务
                            await transaction.RollbackAsync(cancellationToken);
                            res.Msg = "新增医生失败!";
                            res.Code = ApiEnum.Fail;
                            _logger.LogError("新增医生失败");
                            res.Data = r;
                        }
                    }
                    catch (Exception ex)
                    {
                        // 回滚事务
                        await transaction.RollbackAsync(cancellationToken);
                        throw ex;
                    }
                }
                return await Task.FromResult(res);
            }
            catch (Exception ex)
            {
                res.Msg = "新增医生异常: " + ex.Message;
                res.Code = ApiEnum.Fail;
                _logger.LogError($"新增医生异常:{ex.Message}");
                return await Task.FromResult(res);
            }
        }
    }
}